﻿using AutoMapper;
using Microsoft.AspNetCore.SignalR;
using TrackSystem.Contracts;
using TrackSystem.Entities.RequestFeature;
using TrackSystem.IO.Alarm;
using TrackSystem.IO.Data;
using TrackSystem.IO.Equip;
using TrackSystem.IO.Formula;
using TrackSystem.IO.Logics;
using TrackSystem.IO.Loops;
using TrackSystem.IO.Models;
using TrackSystem.IO.Ports;
using TrackSystem.IO.Sensors;
using TrackSystem.IO.Utils;
using TrackSystem.UI.Server.Features;
using LogicItem = TrackSystem.IO.Logics.LogicItem;

namespace TrackSystem.API.SignalRHub
{
    /// <summary>
    /// 传感器控制连接器
    /// </summary>
    /// <param name="wrapper">数据库</param>
    /// <param name="mapper">映射工具</param>
    /// <param name="serviceScope">映射工具</param>
    public class IOControlHub(IRepositoryWrapper wrapper, IMapper mapper, IServiceScopeFactory serviceScope) : Hub
    {
        /// <summary>
        /// 初始化装备列表
        /// </summary>
        /// <returns></returns>
        public async Task InitialEquip()
        {
            ResultMsg result = await EquipFactory.Instance.Load(wrapper, serviceScope);
            await Clients.Caller.SendAsync("HandleInitEquip", result);
        }

        /// <summary>
        /// 卸载装备列表
        /// </summary>
        /// <returns></returns>
        public async Task UnloadEquip()
        {
            EquipFactory.Instance.UnLoad();
            await Clients.Caller.SendAsync("HandleInitEquip", "卸载所有装备成功");
        }

        /// <summary>
        /// 查询所有设备
        /// </summary>
        /// <returns></returns>
        public async Task AcquireEquip()
        {
            var equips = EquipFactory.Instance;
            EquipFactory.Instance.Update();
            IEnumerable<EquipItem> items =  equips.GetAll();
            await Clients.Caller.SendAsync("HandleInitAcquireEquip", items);
        }

        /// <summary>
        /// 根据名称获取部件
        /// </summary>
        /// <param name="partName"></param>
        public async Task AcquirePartByName(string partName)
        {
            PartSelect partSelect = new();
            if (!string.IsNullOrEmpty(partName))
            {
                partSelect.CurrentName = partName;
                if (SensorFactory.Instance.Items.TryGetValue(partName, out var sensor))
                {
                    partSelect.Sensor = sensor.ConvertUnit();
                    partSelect.IsExist = true;
                }

                if (LogicFactory.Instance.Items.TryGetValue(partName, out var logic))
                {
                    partSelect.Logic = logic;
                    partSelect.IsExist = true;                    
                }


                if (LoopFactory.Instance.Items.TryGetValue(partName, out var loop))
                {
                    partSelect.Loop = loop;
                    partSelect.IsExist = true;                    
                }

            }
            await Clients.Caller.SendAsync("HandleAcquirePart", partSelect);
        }
        
        /// <summary>
        /// 初始化传感器列表
        /// </summary>
        /// <returns></returns>
        public async Task InitialSensors()
        {
            ResultMsg result = await SensorFactory.Instance.Load(wrapper);
            await Clients.Caller.SendAsync("HandleInitSensors", result);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task UnloadSensors()
        {
            SensorFactory.Instance.Unload();
            await Clients.Caller.SendAsync("HandleInitSensors", "卸载所有传感器成功");
        }

        /// <summary>
        /// 初始化寄存器列表
        /// </summary>
        /// <returns></returns>
        public async Task InitialRegs()
        {
            ResultMsg? result = RegFactory.Instance.Load(wrapper);
            await Clients.Caller.SendAsync("HandleInitRegs", result);
        }

        /// <summary>
        /// 初始化寄存器列表
        /// </summary>
        /// <returns></returns>
        public async Task UnloadRegs()
        {
            RegFactory.Instance.Disposable();
            await Clients.Caller.SendAsync("HandleInitRegs", ResultMsg.Succ("卸载寄存器成功"));
        }

        /// <summary>
        /// 获取端口信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquireChannelMessage()
        {
            List<IOUnit> ports = new();

            foreach (var port in PortFactory.Instance.Items.Values)
            {
                var portUnit = mapper.Map<IOUnit>(port);
                portUnit.SensorNameList = port.Sensors.Values.OrderBy(a => a.Station).Select(a => a.Name).ToList();
                ports.Add(portUnit);
            }

            await Clients.Caller.SendAsync("HandleChannelStatus", ports);
        }

        /// <summary>
        /// 获取端口信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquirePagedChannelMessage(PageParameter options)
        {
            List<IOUnit> ports = new();

            var items = PortFactory.Instance.Items.Values.Where(a =>
                                    options.Filter != null && (a.Name.Contains(options.Filter, StringComparison.OrdinalIgnoreCase) ||
                                                               a.Description.Contains(options.Filter, StringComparison.OrdinalIgnoreCase)))
                                    .OrderBy(a => a.Name)
                                    .ToList();

            options.TotalCount = items.Count;
            options.TotalPages = (int)Math.Ceiling(options.TotalCount / (double)options.PageSize);
            options.CurrentPage = (options.CurrentPage < options.TotalPages) ? options.CurrentPage : options.TotalPages;
            options.CurrentPage = options.CurrentPage > 0 ? options.CurrentPage : 1;
            items = items.Skip((options.CurrentPage - 1) * options.PageSize).Take(options.PageSize).ToList();


            foreach (var port in items)
            {
                var portUnit = mapper.Map<IOUnit>(port);
                portUnit.SensorNameList = port.Sensors.Values.OrderBy(a => a.Station).Select(a => a.Name).ToList();
                ports.Add(portUnit);
            }

            await Clients.Caller.SendAsync("HandlePagedChannelStatus", ports, options);
        }

        /// <summary>
        /// 获取传感器信息根据名称
        /// </summary>
        /// <returns></returns>
        public async Task AcquireSensorByName(string sensorName)
        {
            if (!string.IsNullOrEmpty(sensorName))
            {
                if (SensorFactory.Instance.Items.TryGetValue(sensorName, out var result))
                {
                    await Clients.Caller.SendAsync("HandleSensorByName", result.ConvertUnit());
                    return;
                }
            }

            await Clients.Caller.SendAsync("HandleSensorByName", null);
        }


        /// <summary>
        /// 查询所有寄存器
        /// </summary>
        /// <returns></returns>
        public async Task AcquireRegMessage()
        {
            if (RegFactory.Instance.Regs is not null)
            {
                var sortDict = RegFactory.Instance.Regs
                    .OrderBy(a => a.Key)
                    .ToDictionary(a => a.Key, b => b.Value);
                await Clients.Caller.SendAsync("HandleRegsStatus", sortDict);
            }
        }

        /// <summary>
        /// 获取分页信息
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public async Task AcquirePagedRegs(PageParameter options)
        {
            var lstRegs = RegFactory.Instance.Regs
                .Where(a => options.Filter != null && a.Key.Contains(options.Filter, StringComparison.OrdinalIgnoreCase))
                .OrderBy(a => a.Key)
                .ToList();

            options.TotalCount = lstRegs.Count;
            options.TotalPages = (int)Math.Ceiling(options.TotalCount / (double)options.PageSize);
            options.CurrentPage = (options.CurrentPage < options.TotalPages)? options.CurrentPage : options.TotalPages;
            options.CurrentPage = (options.CurrentPage > 0) ? options.CurrentPage : 1;
            lstRegs = lstRegs.Skip((options.CurrentPage - 1) * options.PageSize).Take(options.PageSize).ToList();

            await Clients.Caller.SendAsync("HandlePagedRegs", lstRegs, options);
        }
        
        /// <summary>
        /// 变量赋值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        public async Task Assign(string name, OperandDef op)
        {
            RegFactory.Instance[name] = op;
            await Clients.Caller.SendAsync("HandleAssign", ResultMsg.Succ("OK"));
        }

        /// <summary>
        /// 初始化逻辑表达式
        /// </summary>
        /// <returns></returns>
        public async Task InitLogics()
        {
            ResultMsg result = await LogicFactory.Instance.Load(wrapper);
            await Clients.Caller.SendAsync("HandleInitLogics", result);
        }

        /// <summary>
        /// 卸载逻辑表达式
        /// </summary>
        /// <returns></returns>
        public async Task UnloadLogics()
        {
            LogicFactory.Instance.Unload();
            await Clients.Caller.SendAsync("HandleInitLogics", ResultMsg.Succ("卸载逻辑表达式成功"));
        }


        /// <summary>
        /// 获取逻辑回路信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquireLogicMessage()
        {
            List<LogicItem> lstLogics = LogicFactory.Instance.Items.Values
                .OrderBy(a => a.Name)
                .ToList();
            await Clients.Caller.SendAsync("HandleLogicStatus", lstLogics);
        }

        /// <summary>
        /// 按照页面获取逻辑回路信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquirePagedLogicMessage(PageParameter options)
        {
            var lstLogics = LogicFactory.Instance.Items.Values
                    .Where(a => 
                    options.Filter != null && (a.Name.Contains(options.Filter, StringComparison.OrdinalIgnoreCase) ||
                                               a.clacFormula.Contains(options.Filter, StringComparison.OrdinalIgnoreCase) ||
                                               a.condFormula.Contains(options.Filter, StringComparison.OrdinalIgnoreCase)))
                    .OrderBy(a => a.Name)
                    .ToList();

            options.TotalCount = lstLogics.Count;
            options.TotalPages = (int)Math.Ceiling(options.TotalCount / (double)options.PageSize);
            options.CurrentPage = (options.CurrentPage < options.TotalPages) ? options.CurrentPage : options.TotalPages;
            options.CurrentPage = (options.CurrentPage > 0) ? options.CurrentPage : 1;
            lstLogics = lstLogics.Skip((options.CurrentPage - 1) * options.PageSize).Take(options.PageSize).ToList();

            await Clients.Caller.SendAsync("HandlePagedLogicStatus", lstLogics, options);
        }

        /// <summary>
        /// 初始化控制回路
        /// </summary>
        /// <returns></returns>
        public async Task InitLoops()
        {
            var result = await LoopFactory.Instance.Load(wrapper);
            await Clients.Caller.SendAsync("HandleInitLoops", result);
        }

        /// <summary>
        /// 卸载控制回路
        /// </summary>
        /// <returns></returns>
        public async Task UnloadLoops()
        {
            LoopFactory.Instance.Unload();
            await Clients.Caller.SendAsync("HandleInitLoops", ResultMsg.Succ("卸载控制回路成功"));
        }


        /// <summary>
        /// 获取控制回路信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquireLoopMessage()
        {
            List<LoopItem> lstLogics = LoopFactory.Instance.Items.Values
                .OrderBy(a => a.Name)
                .ToList();
            await Clients.Caller.SendAsync("HandleLoopStatus", lstLogics);
        }

        /// <summary>
        /// 获取控制回路信息
        /// </summary>
        /// <returns></returns>
        public async Task AcquireSingleLoop(string loopName)
        {
            if (!string.IsNullOrEmpty(loopName))
            {
                if (LoopFactory.Instance.Items.TryGetValue(loopName, out var item))
                {
                    await Clients.Caller.SendAsync("HandleSingleLoop", item);
                    return;
                }
            }

            await Clients.Caller.SendAsync("HandleSingleLoop", null);
        }


        /// <summary>
        /// 查询回路列表
        /// </summary>
        /// <returns></returns>
        public async Task AccquireLoopName()
        {
            var loopNameList = wrapper.Loop.GetAll().Select(a => a.Name).ToList();
            await Clients.Caller.SendAsync("HandleLoopName", loopNameList);
        }

        /// <summary>
        /// 存储回路设置信息到数据库中
        /// </summary>
        /// <param name="loopName"></param>
        public async Task DataSaveToTable(string loopName)
        {
            if (LoopFactory.Instance.Items.TryGetValue(loopName, out var loop))
            {
                await loop.SaveDataToTable(wrapper);
                await Clients.Caller.SendAsync("HandleLoopName", "保存数据成功");
                return;
            }
            await Clients.Caller.SendAsync("HandleLoopName", "保存数据失败");
        }

        /// <summary>
        /// 获取报警信息
        /// </summary>
        public async Task AcquireAlarmMessage()
        {
            int num = AlarmFactory.Instance.TotalAlarmNum;
            await Clients.Caller.SendAsync("HandleAcquireAlarmMessage", AlarmFactory.Instance.AcquireAlarm(), num);
        }

        /// <summary>
        /// 确认报警信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task ConfirmAlarm(Guid id)
        {
            AlarmFactory.Instance.ConfirmAlarm(id);
            await Clients.Caller.SendAsync("HandleAlarmMessage", "确认报警成功");
        }

        /// <summary>
        /// 隐藏报警
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task HiddenAlarm(Guid id)
        {
            AlarmFactory.Instance.HiddenAlarm(id);
            await Clients.Caller.SendAsync("HandleAlarmMessage", "隐藏报警成功");
        }

        /// <summary>
        /// 显示所有报警
        /// </summary>
        /// <returns></returns>
        public async Task BtnShowAllAlarm()
        {
            AlarmFactory.Instance.ShowAllAlarm();
            await Clients.Caller.SendAsync("HandleAlarmMessage", "显示所有报警成功");
        }

    }
}
